home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / video / fly8111-.000 / fly8111- / fly8 / COMMON / bgr.c next >
C/C++ Source or Header  |  1979-12-31  |  6KB  |  333 lines

  1. /* --------------------------------- bgr.c ---------------------------------- */
  2.  
  3. /* This is part of the flight simulator 'fly8'.
  4.  * Author: Eyal Lebedinsky (eyal@ise.canberra.edu.au).
  5. */
  6.  
  7. /* Drawing primitives for a dumb buffer with 1 byte per pixel.
  8.  * Can be very fast when usage of low level assembly support is available.
  9.  *
  10.  * bSetActive (base)
  11.  * bSetSize (width, height, xbytes)
  12.  * bMoveTo (x, y)
  13.  * bDrawTo (x, y, color)
  14.  * bDrawLine (x0, y0, x1, y1, color)
  15.  * bSetWriteMode (mode)
  16.  * bScrClear (x, y, sizex, sizey, color)
  17.  * bDrawEllipse (cx, cy, rx, ry, color)
  18. */
  19.  
  20. #include "fly.h"
  21. #include "bgr.h"
  22.  
  23.  
  24. static int    bGrWriteMode = T_MSET;
  25. static char    BPTR *bActiveBase = 0;
  26. static Uint    bWidth = 0, bHeight = 0, bXbytes = 0;
  27. static Uint    x1 = 0, y1 = 0, xydone = 0;
  28. static char    BPTR *pva = 0;
  29.  
  30. extern int FAR
  31. bSetActive (char BPTR *base)
  32. {
  33.     bActiveBase = base;
  34.     return (0);
  35. }
  36.  
  37. extern int FAR
  38. bSetSize (Uint width, Uint height, Uint xbytes)
  39. {
  40.     bWidth  = width;
  41.     bHeight = height;
  42.     bXbytes = xbytes;
  43.     return (0);
  44. }
  45.  
  46. #ifndef USE_ASMLINE
  47.  
  48. #define SLoop    bSimpleLoop
  49. #define ILoop    bInnerLoop
  50. #define vgaset    memset
  51.  
  52. #if UNROLL_DO_LINE
  53. #define DO_LINE(op) \
  54.     while ((count -= 4) >= 0) { \
  55.         DO_PIXEL (op) \
  56.         DO_PIXEL (op) \
  57.         DO_PIXEL (op) \
  58.         DO_PIXEL (op) \
  59.     } \
  60.     switch (count) { \
  61.     case -1:    DO_PIXEL (op) \
  62.     case -2:    DO_PIXEL (op) \
  63.     case -3:    DO_PIXEL (op) \
  64.     }
  65. #else
  66. #define DO_LINE(op) \
  67.     while (--count >= 0) { \
  68.         DO_PIXEL (op) \
  69.     }
  70. #endif
  71.  
  72. #define DO_MODE_LINE \
  73.     if (T_MSET == bGrWriteMode) { \
  74.         DO_LINE (=) \
  75.     } else if (T_MOR == bGrWriteMode) { \
  76.         DO_LINE (|=) \
  77.     } else /* if (T_MXOR == bGrWriteMode) */ { \
  78.         DO_LINE (^=) \
  79.     }
  80.  
  81. INLINED static char BPTR * NEAR
  82. SLoop (iva, count, sv, c)
  83. char    BPTR *iva;
  84. int    count;
  85. int    sv;
  86. int    c;
  87. {
  88. #define DO_PIXEL(op) \
  89.     *(iva += sv) op c;
  90.  
  91.     DO_MODE_LINE
  92.  
  93. #undef DO_PIXEL
  94.  
  95.     return (iva);
  96. }
  97.  
  98. INLINED static char BPTR * NEAR
  99. ILoop (iva, dy, dx, dvx, dvy, c)
  100. register char    BPTR *iva;
  101. register Uint    dy;
  102. Uint        dx;
  103. register int    dvx;
  104. int        dvy;
  105. int        c;
  106. {
  107.     register short    err;
  108.     short        count;
  109.  
  110. /* dx > dy  never == !!!
  111.  * dx > 0
  112.  * dy >= 0
  113. */
  114.  
  115.     count = dx;
  116.     err = dx >> 1;
  117.  
  118. #define DO_PIXEL(op) \
  119.     iva += dvx; \
  120.     if ((err -= dy) < 0) { \
  121.         err += dx; \
  122.         iva += dvy; \
  123.     } \
  124.     *iva op c;
  125.  
  126.     DO_MODE_LINE
  127.  
  128. #undef DO_PIXEL
  129.  
  130.     return (iva);
  131. }
  132. #undef DO_LINE
  133. #undef DO_MODE_LINE
  134. #endif
  135.  
  136. extern void FAR
  137. bMoveTo (Uint x, Uint y)
  138. {
  139. #if DEBUG_BGR
  140.     if (x >= bWidth)
  141.         x = bWidth-1;
  142.     if (y >= bHeight)
  143.         y = bHeight-1;
  144. #endif
  145.     x1 = x;
  146.     y1 = y;
  147.     xydone = 0;
  148. }
  149.  
  150. extern void FAR
  151. bDrawTo (Uint x2, Uint y2, Uint c)
  152. {
  153.     int    dx, dy, svx, svy;
  154.     int    t;
  155.  
  156. #if DEBUG_BGR
  157.     if (x2 >= bWidth)
  158.         x2 = bWidth-1;
  159.     if (y2 >= bHeight)
  160.         y2 = bHeight-1;
  161. #endif
  162.     t = 0;
  163.     if (!xydone) {
  164.         t = 1;
  165.         xydone = 1;
  166.         pva = bActiveBase + x1 + y1*(long)bXbytes;
  167.         if (T_MSET == bGrWriteMode)
  168.             *pva = c;
  169.         else if (T_MOR == bGrWriteMode)
  170.             *pva |= c;
  171.         else if (T_MXOR == bGrWriteMode)
  172.             *pva ^= c;
  173.     }
  174.  
  175.     svx = 1;
  176.     if ((dx = x2 - x1) < 0) {
  177.         dx = -dx;
  178.         svx = -1;
  179.     }
  180.  
  181.     svy = bXbytes;
  182.     if ((dy = y2 - y1) < 0) {
  183.         dy = -dy;
  184.         svy = -svy;
  185.     }
  186.  
  187.     if (dx > dy) {
  188.         if (dy)
  189.             pva = ILoop (pva, dy, dx, svx, svy, c);
  190.         else {
  191.             if (T_MSET != bGrWriteMode)
  192.                 pva = SLoop (pva, dx, svx, c);
  193.             else {
  194.                 char    BPTR *pvb;
  195.  
  196.                 pvb = pva + x2 - x1;        /* end point */
  197.                 vgaset ((svx>0 ? (pva+1) : pvb), c, dx);
  198.                 pva = pvb;
  199.             }
  200.         }
  201.         ++GrStats[dx+t];
  202.     } else if (dx < dy) {
  203.         if (dx)
  204.             pva = ILoop (pva, dx, dy, svy, svx,  c);
  205.         else
  206.             pva = SLoop (pva, dy, svy, c);
  207.         ++GrStats[dy+t];
  208.     } else /* if (dx == dy) */ {
  209.         if (dx)
  210.             pva = SLoop (pva, dy, svx+svy, c);
  211.         ++GrStats[dx+t];
  212.     }
  213.  
  214.     x1 = x2;
  215.     y1 = y2;
  216. }
  217.  
  218. extern void FAR
  219. bDrawLine (Uint xa, Uint ya, Uint xb, Uint yb, Uint c)
  220. {
  221.     if (xa != x1 || ya != y1 || !xydone)
  222.         bMoveTo (xa, ya);
  223.  
  224.     bDrawTo (xb, yb, c);
  225. }
  226.  
  227. extern int FAR
  228. bSetWriteMode (int mode)
  229. {
  230.     bGrWriteMode = mode;
  231.     return (0);
  232. }
  233.  
  234. extern void FAR
  235. bScrClear (Uint x, Uint y, Uint sizex, Uint sizey, Uint color)
  236. {
  237.     for (sizey += y, sizex += x-1; y < sizey; ++y)
  238.         bDrawLine (x, y, sizex, y, color);
  239. }
  240.  
  241. /* Based on the version from ACM TOG V11N3 (July 1992), this one is
  242.  * modified to do 2 quads at a time to reduce VGA page flips.
  243. */
  244.  
  245. #define POINT(x,y,c) \
  246.     do {                        \
  247.         if (T_MSET == bGrWriteMode)        \
  248.             *(xxyy+(x)+(y))  = (Uchar)(c);    \
  249.         else if (T_MOR == bGrWriteMode)        \
  250.             *(xxyy+(x)+(y)) |= (c);        \
  251.         else if (T_MXOR == bGrWriteMode)    \
  252.             *(xxyy+(x)+(y)) ^= (c);        \
  253.     } while (0)
  254.  
  255. #define INCX() \
  256.     (x++, b2x += b2, dxt += d2xt, t += dxt)
  257.  
  258. #define INCY() \
  259.     (y--, a2y -= a2, dyt += d2yt, t += dyt, yy -= bXbytes)
  260.  
  261. extern void FAR
  262. bDrawEllipse (Uint xc, Uint yc, Uint a, Uint b, Uint c)
  263. {
  264.     char    BPTR *xxyy;
  265.     int    x, y;
  266.     long    yy, a2, b2, crit1, crit2, crit3, t, dxt, dyt, d2xt, d2yt;
  267.     long    b2x, a2y;
  268.  
  269.     if (xc < a || xc+a >= bWidth ||
  270.         yc < b || yc+b >= bHeight)
  271.         return;
  272.     xxyy = bActiveBase + xc + yc * (long)bXbytes;
  273.  
  274.     x = 0;
  275.     y = b;
  276.     yy = y * (long)bXbytes;
  277.     a2 = (long)a * a;
  278.     b2 = (long)b * b;
  279.     crit1 = -(a2/4 + a%2 + b2);
  280.     crit2 = -(b2/4 + b%2 + a2);
  281.     crit3 = -(b2/4 + b%2);
  282.     t = -a2 * y;
  283.     dxt =  2 * b2 * x;
  284.     dyt = -2 * a2 * y;
  285.     d2xt = 2 * b2;
  286.     d2yt = 2 * a2;
  287.     b2x = b2 * x;
  288.     a2y = a2 * y;
  289.  
  290.     while (y >= 0 && x <= (int)a) {
  291.         POINT (x, yy, c);
  292.         if (x && y)
  293.             POINT (-x, yy, c);
  294.         if (t + b2x <= crit1 || t + a2y <= crit3)
  295.             INCX ();
  296.         else if (t - a2y > crit2)
  297.             INCY ();
  298.         else {
  299.             INCX ();
  300.             INCY ();
  301.         }
  302.     }
  303.  
  304.     x = 0;
  305.     y = b;
  306.     yy = y * (long)bXbytes;
  307.     t = -a2 * y;
  308.     dxt =  2 * b2 * x;
  309.     dyt = -2 * a2 * y;
  310.     d2xt = 2 * b2;
  311.     d2yt = 2 * a2;
  312.     b2x = b2 * x;
  313.     a2y = a2 * y;
  314.  
  315.     while (y >= 0 && x <= (int)a) {
  316.         if (x || y)
  317.             POINT (-x, -yy, c);
  318.         if (x && y)
  319.             POINT ( x, -yy, c);
  320.         if (t + b2x <= crit1 || t + a2y <= crit3)
  321.             INCX ();
  322.         else if (t - a2y > crit2)
  323.             INCY ();
  324.         else {
  325.             INCX ();
  326.             INCY ();
  327.         }
  328.     }
  329. }
  330. #undef POINT
  331. #undef INCX
  332. #undef INCY
  333.